import jwt
from django.http import JsonResponse


class AuthMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # 配置白名单，这些路径不需要进行认证
        self.whitelist = [
            '/user/captcha/',
            '/user/sendcode/',
            '/user/loginByCode/',
            '/user/loginByCode/',
            # 可以添加更多不需要认证的路径
        ]

    def __call__(self, request):
        # 检查请求路径是否在白名单中
        if self.is_whitelisted(request.path_info):
            return self.get_response(request)

        # 从请求头中获取 token
        token = self.extract_token(request)
        if not token:
            return JsonResponse({'error': '未提供认证 token'}, status=401)

        try:
            # 验证 token 的有效性和过期时间
            payload = self.verify_token(token)
            # 获取用户信息
            user = self.get_user(payload)
            # 将用户信息存储到 request 中，以便后续视图使用
            request.user = user

            # 检查权限（这里只是示例，具体实现根据项目需求调整）
            if not self.has_permission(user, request):
                return JsonResponse({'error': '权限不足'}, status=403)

        except TokenExpiredError:
            return JsonResponse({'error': 'Token 已过期'}, status=401)
        except InvalidTokenError:
            return JsonResponse({'error': '无效的 Token'}, status=401)
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=400)

        response = self.get_response(request)
        return response

    def is_whitelisted(self, path):
        """检查路径是否在白名单中"""
        return any(whitelisted_path in path for whitelisted_path in self.whitelist)

    def extract_token(self, request):
        """从请求头中提取 token"""
        auth_header = request.META.get('HTTP_AUTHORIZATION')
        if not auth_header:
            return None
        # 假设 token 格式为 "Bearer <token>"
        parts = auth_header.split()
        if len(parts) != 2 or parts[0].lower() != 'bearer':
            return None
        return parts[1]

    def verify_token(self, token):
        """验证 token 的有效性和过期时间"""
        # 这里需要根据你的 token 生成方式进行验证
        # 例如，使用 PyJWT 验证 JWT token
        try:
            # SECRET_KEY 应该从 Django 设置中获取
            from django.conf import settings
            payload = jwt.decode(token, settings.SECRET_KEY, algorithms=['HS256'])
            return payload
        except jwt.ExpiredSignatureError:
            raise TokenExpiredError("Token 已过期")
        except jwt.InvalidTokenError:
            raise InvalidTokenError("无效的 Token")

    def get_user(self, payload):
        """从 token 载荷中获取用户信息"""
        # 这里需要根据你的 token 结构和用户模型进行调整
        global User
        user_id = payload.get('user_id')
        if not user_id:
            raise InvalidTokenError("Token 中缺少用户信息")
        try:
            # 假设使用 Django 的默认用户模型
            from django.contrib.auth.models import User
            return User.objects.get(id=user_id)
        except User.DoesNotExist:
            raise InvalidTokenError("无效的用户")

    def has_permission(self, user, request):
        """检查用户是否有权限访问请求的资源"""
        # 这里可以根据项目需求实现复杂的权限检查
        # 例如，检查用户角色、用户组、请求方法等
        # 示例：只允许管理员访问某些接口
        if request.path_info.startswith('/api/admin/') and not user.is_superuser:
            return False
        return True

# 自定义异常类
class TokenExpiredError(Exception):
    pass

class InvalidTokenError(Exception):
    pass